
#include "OgreApplication.h"


OgreApplication* MenuHandler::ogre_app = NULL;

MenuHandler::MenuHandler(OgreApplication *ogre_app){

	MenuHandler::ogre_app = ogre_app;
	
	this->initNull();
	this->initCEGUI();
	this->initWindowVector();

}

void MenuHandler::initNull(){

	this->gCEGUIOgreRenderer		= NULL;
	this->windows					= NULL;

	this->captureControls			= false;
	this->captureKeyboard			= false;
	this->captureMouse				= false;

	this->debug_bar					= NULL;
	this->console					= NULL;
	this->hint_wind					= NULL;					

}

void MenuHandler::initCEGUI(){

	this->gCEGUIOgreRenderer = &CEGUI::OgreRenderer::bootstrapSystem(*(MenuHandler::ogre_app->getMainWindow()));
        this->gCEGUIOgreRenderer->setRenderingEnabled(false);
        //load resources


        for(int i = 0; i < 5;i++){
        
                Ogre::String cur= "";
        
                switch(i){
                case 0:cur ="fonts";break;
                case 1:cur ="layouts";break;
                case 2:cur ="schemes";break;
                case 3:cur ="looknfeel";break;
                case 4:cur ="imagesets";break;
                }


                Ogre::String mResGroupName = "CEGUI"+cur;
                Ogre::String mLocation =MenuHandler::ogre_app->getInitSettings()->relative_path+"\\CEGUI\\"+cur;


                MenuHandler::ogre_app->getResourceGroupManager()->createResourceGroup(mResGroupName);
                MenuHandler::ogre_app->getResourceGroupManager()->addResourceLocation( mLocation,"FileSystem",mResGroupName,false);
                MenuHandler::ogre_app->getResourceGroupManager()->loadResourceGroup(mResGroupName);
        }


        CEGUI::Imageset::setDefaultResourceGroup("CEGUIimagesets");
        CEGUI::Font::setDefaultResourceGroup("CEGUIfonts");
        CEGUI::Scheme::setDefaultResourceGroup("CEGUIschemes");
        CEGUI::WidgetLookManager::setDefaultResourceGroup("CEGUIlooknfeel");
        CEGUI::WindowManager::setDefaultResourceGroup("CEGUIlayouts");
        
        
        CEGUI::SchemeManager::getSingleton().create("TaharezLook.scheme");
        
        CEGUI::Window *guiRoot = CEGUI::WindowManager::getSingleton().loadWindowLayout("Blank.layout"); 
        CEGUI::System::getSingleton().setGUISheet(guiRoot);
	
}

void MenuHandler::initWindowVector(){
	if(this->windows == NULL)this->windows = new std::vector<MenuWindow*>();
}

MenuHandler::~MenuHandler(){

	this->setCapturingControls(false,false,false);

	
	this->destroyWindowVector();
	this->destroyCEGUI();

}

void MenuHandler::destroyCEGUI(){

	if(this->gCEGUIOgreRenderer != NULL){
        
        this->gCEGUIOgreRenderer->destroy(*this->gCEGUIOgreRenderer);
        this->gCEGUIOgreRenderer = NULL;
	}
}

void MenuHandler::destroyWindowVector(){
	if(this->windows == NULL)return;
		
	for(unsigned int i = 0; i < this->windows->size();i++){
		delete this->windows->at(i);
	}

	this->windows->clear();
	delete this->windows;
	this->windows = NULL;
}

// window vector methods

void MenuHandler::addWindow(Ogre::String name){

	if(this->getIndex(name) != -1)return;
	
	this->windows->push_back(new MenuWindow(name,true));

}

bool MenuHandler::isAnyWindowShown(){
	
	for(unsigned int i = 0; i < this->windows->size();i++){
		if(this->windows->at(i)->isShown()) return true;
	}

	return false;
}

int MenuHandler::getIndex(Ogre::String name){
	if(this->windows == NULL)return -1;

	for(unsigned int i = 0; i < this->windows->size();i++){
		if(this->windows->at(i)->getName().compare(name)== 0)return i;
	}
	
	return -1;
}

bool MenuHandler::doesExist(Ogre::String name){
	return (this->getIndex(name) != -1);
}

MenuWindow* MenuHandler::getWindow(int index){
	if(this->windows == NULL)return NULL;
	if(index < 0 || index >= (int) this->windows->size())return NULL;
	return this->windows->at(index);
}

MenuWindow* MenuHandler::getWindow(Ogre::String name){
	return this->getWindow(this->getIndex(name));
}

// control methods


bool MenuHandler::isCapturingControls(){
	return this->captureControls;
}

bool MenuHandler::isCapturingKeyboard(){
	return this->captureKeyboard;
}

bool MenuHandler::isCapturingMouse(){
	return this->captureMouse;
}

void MenuHandler::setCapturingControls(bool state,bool mouse,bool keyboard){
	  
	bool change = (this->captureControls ^ state)||(mouse ^ this->captureMouse)||(keyboard ^ this->captureKeyboard);

	if(change){
			this->removeCaptures();
			this->setCaptures();
	}
}

void MenuHandler::removeCaptures(){

	KeyboardMouseHandler* hand = MenuHandler::ogre_app->getKeyboardMouseHandler();

	if(hand == NULL)return;
	
	if(hand->getKeyboard() != NULL)hand->getKeyboard()->setEventCallback(NULL);
	
	if(hand->getMouse() != NULL) hand->getMouse()->setEventCallback(NULL);
}

void MenuHandler::setCaptures(){

	if(! this->captureControls)return;

KeyboardMouseHandler* hand = MenuHandler::ogre_app->getKeyboardMouseHandler();

	if(hand == NULL)return;
	
	if(hand->getKeyboard() != NULL && this->captureKeyboard)hand->getKeyboard()->setEventCallback(this);
	
	if(hand->getMouse() != NULL && this->captureMouse) hand->getMouse()->setEventCallback(this);

}

//debug bar

void MenuHandler::showDebugBar(){
	if(this->debug_bar == NULL){
		this->debug_bar = new DebugBar(MenuHandler::ogre_app->getMainWindow());
		this->windows->push_back(this->debug_bar);
	}
	
		this->debug_bar->show();
	
}

void MenuHandler::closeDebugBar(){
	if(this->debug_bar == NULL)return;
	this->debug_bar->hide();
}

void MenuHandler::showConsole(){
	if(this->console == NULL){
	this->console = new Console();
	
	this->windows->push_back(this->console);
	}

	this->console->show();
	this->console->setActive();
}

void MenuHandler::closeConsole(){
if(this->console == NULL)return;
	this->console->hide();
}

void MenuHandler::hint(Ogre::String text){
	if(this->hint_wind == NULL){
		this->hint_wind = new HintWindow(MenuHandler::ogre_app->getInitSettings()->hintTimeout);
		this->windows->push_back(this->hint_wind);
	}
	
	this->hint_wind->addText(text);
}

//cegui methods

// OIS::KeyListener

CEGUI::MouseButton MenuHandler::convertButton(OIS::MouseButtonID buttonID)
{
    switch (buttonID)
    {
    case OIS::MB_Left:
        return CEGUI::LeftButton;
 
    case OIS::MB_Right:
        return CEGUI::RightButton;
 
    case OIS::MB_Middle:
        return CEGUI::MiddleButton;
 
    default:
        return CEGUI::LeftButton;
    }
}

bool MenuHandler::keyPressed( const OIS::KeyEvent &arg ){
CEGUI::System &sys = CEGUI::System::getSingleton();
sys.injectKeyDown(arg.key);
sys.injectChar(arg.text);

//update console

if(this->console != NULL && arg.key == OIS::KC_RETURN){

	this->console->handleInput();

}

return true;
}
bool MenuHandler::keyReleased( const OIS::KeyEvent &arg ){
CEGUI::System::getSingleton().injectKeyUp(arg.key);
return true;
}
    // OIS::MouseListener
bool MenuHandler::mouseMoved( const OIS::MouseEvent &arg ){
CEGUI::System &sys = CEGUI::System::getSingleton();
sys.injectMouseMove(arg.state.X.rel, arg.state.Y.rel);
// Scroll wheel.
if (arg.state.Z.rel)
    sys.injectMouseWheelChange(arg.state.Z.rel / 120.0f);
return true;
}
bool MenuHandler::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id ){
CEGUI::System::getSingleton().injectMouseButtonDown(convertButton(id));
return true;
}
bool MenuHandler::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id ){
CEGUI::System::getSingleton().injectMouseButtonUp(convertButton(id));
return true;
}

void MenuHandler::update(unsigned long millis){

	

	
	if(this->hint_wind != NULL)this->hint_wind->update(millis);

	if(! this->isAnyWindowShown())return;
	
	if(this->debug_bar != NULL)this->debug_bar->update();
	if(this->gCEGUIOgreRenderer != NULL)CEGUI::System::getSingleton().renderGUI();
}
